﻿using System;
using NServiceBus.Saga;
using NHibernate;
using NHibernate.Criterion;


namespace Subscriber1
{
    public class MySagaPersister : ISagaPersister, IDisposable
    {
        public MySagaPersister(ISessionFactory sessionFactory)
        {
            SessionFactory = sessionFactory;
            Session = sessionFactory.OpenSession();
        }

        public ISessionFactory SessionFactory { get; set; }
        public ISession Session { get; set; }

        #region ISagaPersister Members
        public void Save(ISagaEntity saga)
        {
            Session.Save(saga);
        }

        public void Update(ISagaEntity saga)
        {
            Session.Merge(saga);
        }

        public T Get<T>(Guid sagaId) where T : ISagaEntity
        {
            return Session.CreateCriteria(typeof(T), "b")
                        .Add(Restrictions.Eq("b.ProcessId", sagaId))
                        .SetFetchMode("b.Children", FetchMode.Eager)
                        .SetCacheable(true)
                        .SetCacheMode(CacheMode.Normal)
                        .UniqueResult<T>();
            
        }

        public T Get<T>(string property, object value) where T : ISagaEntity
        {
            return Session.CreateCriteria(typeof(T), "b")
                        .Add(Restrictions.Eq("b." + property, value))
                        .SetFetchMode("b.Children", FetchMode.Eager)
                        .UniqueResult<T>();
        }

        public void Complete(ISagaEntity saga)
        {
            Session.Delete(saga);
        }
        #endregion


        #region IDisposable Members
        void IDisposable.Dispose()
        {
            if (Session == null) return;
            if (!Session.IsOpen) return;

            Session.Close();
            Session.Dispose();
        }

        #endregion
    }
}
